home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / javax / swing / JInternalFrame.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  58.2 KB  |  1,793 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)JInternalFrame.java    1.79 98/08/31
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package javax.swing;
  16.  
  17. import java.awt.*;
  18. import java.awt.event.*;
  19.  
  20. import java.beans.PropertyVetoException;
  21. import java.beans.PropertyChangeEvent;
  22. import java.util.EventListener;
  23.  
  24. import javax.swing.border.Border;
  25. import javax.swing.event.InternalFrameEvent;
  26. import javax.swing.event.InternalFrameListener;
  27. import javax.swing.plaf.*;
  28.  
  29. import javax.accessibility.*;
  30.  
  31. import java.io.ObjectOutputStream;
  32. import java.io.ObjectInputStream;
  33. import java.io.IOException;
  34.  
  35.  
  36. /**
  37.  * A lightweight object that provides many of the features of
  38.  * a native frame, including dragging, closing, becoming an icon,
  39.  * resizing, title display, and support for a menu bar. Generally,
  40.  * you create an instance and add it to a JDesktopPane. Look and
  41.  * feel specific-actions are then (automatically??) delegated to the 
  42.  * DesktopManager object maintained by the JDesktopPane (as set by
  43.  * the UI).
  44.  * <p>
  45.  * The JInternalFrame <code>contentPane</code> is where you add child components.
  46.  * So, to create a JInternalFrame that has a number of buttons arranged 
  47.  * with a BorderLayout object, you might do something like this:
  48.  * <PRE>
  49.  *    JComponent c = (JComponent) frame.getContentPane();
  50.  *    c.setLayout(new BorderLayout());
  51.  *    c.add(new JButton(), BorderLayout.NORTH);
  52.  *    c.add(new JButton(), BorderLayout.CENTER);
  53.  * </PRE>
  54.  * The <code>contentPane</code> is actually managed by an instance of JRootPane,
  55.  * which also manages a <code>layoutPane</code>, <code>glassPane</code>, and 
  56.  * optional <code>menuBar</code> for the frame. Please see the JRootPane 
  57.  * documentation for a complete description of these components.
  58.  * <p>
  59.  * For the keyboard keys used by this component in the standard Look and
  60.  * Feel (L&F) renditions, see the
  61.  * <a href="doc-files/Key-Index.html#JInternalFrame">JInternalFrame</a> key assignments.
  62.  * <p>
  63.  * <strong>Warning:</strong>
  64.  * Serialized objects of this class will not be compatible with 
  65.  * future Swing releases.  The current serialization support is appropriate
  66.  * for short term storage or RMI between applications running the same
  67.  * version of Swing.  A future release of Swing will provide support for
  68.  * long term persistence.
  69.  *
  70.  * @see JDesktopPane
  71.  * @see DesktopManager
  72.  * @see JInternalFrame.JDesktopIcon
  73.  * @see JRootPane
  74.  *
  75.  * @version 1.79 08/31/98
  76.  * @author David Kloba
  77.  * @author Rich Schiavi
  78.  * @beaninfo
  79.  *      attribute: isContainer true
  80.  *      attribute: containerDelegate getContentPane
  81.  *      description: A frame container which is contained within 
  82.  *                   another window.
  83.  */
  84. public class JInternalFrame extends JComponent implements 
  85.         Accessible, WindowConstants,
  86.         RootPaneContainer
  87. {
  88.     /**
  89.      * @see #getUIClassID
  90.      * @see #readObject
  91.      */
  92.     private static final String uiClassID = "InternalFrameUI";
  93.  
  94.     /**
  95.      * The JRootPane instance that manages the <code>contentPane</code> 
  96.      * and optional <code>menuBar</code> for this frame, as well as the 
  97.      * <code>glassPane</code>.
  98.      *
  99.      * @see JRootPane
  100.      * @see RootPaneContainer
  101.      */
  102.     protected JRootPane rootPane;
  103.  
  104.     /**
  105.      * If true then calls to <code>add</code> and <code>setLayout</code>
  106.      * cause an exception to be thrown.  
  107.      */
  108.     protected boolean rootPaneCheckingEnabled = false;
  109.  
  110.     /** The frame can be closed. */
  111.     protected boolean closable;
  112.     /** The frame has been closed. */
  113.     protected boolean isClosed;
  114.     /** The frame can be expanded to the size of the desktop pane. */
  115.     protected boolean maximizable;
  116.     /** 
  117.      * The frame has been expanded to its maximum size.
  118.      * @see #maximizable
  119.      */
  120.     protected boolean isMaximum;   
  121.     /** 
  122.      * The frame can "iconized" (shrunk down and displayed as
  123.      * an icon-image). 
  124.      * @see JInternalFrame.JDesktopIcon
  125.      */
  126.     protected boolean iconable;
  127.     /** 
  128.      * The frame has been iconized. 
  129.      * @see #iconable
  130.      */
  131.     protected boolean isIcon;   
  132.     /** The frame's size can be changed. */
  133.     protected boolean resizable;
  134.     /** The frame is currently selected. */
  135.     protected boolean isSelected;
  136.     /** The icon shown in the top-left corner of the frame. */
  137.     protected Icon frameIcon;
  138.     /** The title displayed in the frame's title bar. */
  139.     protected String  title;
  140.     /** 
  141.      * The icon that is displayed when the frame is iconized.
  142.      * @see #iconable
  143.      */
  144.     protected JDesktopIcon desktopIcon;
  145.  
  146.     private boolean opened;
  147.  
  148.     private int defaultCloseOperation = HIDE_ON_CLOSE;
  149.  
  150.     /** Bound property name. */
  151.     public final static String CONTENT_PANE_PROPERTY = "contentPane";
  152.     /** Bound property name. */
  153.     public final static String MENU_BAR_PROPERTY = "menuBar";
  154.     /** Bound property name. */
  155.     public final static String TITLE_PROPERTY = "title";
  156.     /** Bound property name. */
  157.     public final static String LAYERED_PANE_PROPERTY = "layeredPane";
  158.     /** Bound property name. */
  159.     public final static String ROOT_PANE_PROPERTY = "rootPane";
  160.     /** Bound property name. */
  161.     public final static String GLASS_PANE_PROPERTY = "glassPane";
  162.     /** Bound property name. */
  163.     public final static String FRAME_ICON_PROPERTY = "frameIcon";
  164.  
  165.     /** Constrained property name indicated that this frame has selected status. */
  166.     public final static String IS_SELECTED_PROPERTY = "selected";
  167.     /** Constrained property name indicating that the frame is closed. */
  168.     public final static String IS_CLOSED_PROPERTY = "closed";
  169.     /** Constrained property name indicating that the frame is maximized. */
  170.     public final static String IS_MAXIMUM_PROPERTY = "maximum";
  171.     /** Constrained property name indicating that the frame is iconified. */
  172.     public final static String IS_ICON_PROPERTY = "icon";
  173.  
  174.  
  175.  
  176.     /** 
  177.      * Creates a non-resizable, non-closable, non-maximizable,
  178.      * non-iconifiable JInternalFrame with no title.
  179.      */
  180.     public JInternalFrame() {
  181.         this("", false, false, false, false);
  182.     }
  183.  
  184.     /** 
  185.      * Creates a non-resizable, non-closable, non-maximizable,
  186.      * non-iconifiable JInternalFrame with the specified title.
  187.      *
  188.      * @param title  the String to display in the title bar.
  189.      */
  190.     public JInternalFrame(String title) {
  191.         this(title, false, false, false, false);
  192.     }
  193.  
  194.     /** 
  195.      * Creates a non-closable, non-maximizable, non-iconifiable 
  196.      * JInternalFrame with the specified title and with resizability 
  197.      * specified.
  198.      *
  199.      * @param title      the String to display in the title bar.
  200.      * @param resizable  if true, the frame can be resized
  201.      */
  202.     public JInternalFrame(String title, boolean resizable) {
  203.         this(title, resizable, false, false, false);
  204.     }
  205.  
  206.     /** 
  207.      * Creates a non-maximizable, non-iconifiable JInternalFrame with the
  208.      * specified title and with resizability and closability specified.
  209.      *
  210.      * @param title      the String to display in the title bar.
  211.      * @param resizable  if true, the frame can be resized
  212.      * @param closable   if true, the frame can be closed
  213.      */
  214.     public JInternalFrame(String title, boolean resizable, boolean closable) {
  215.         this(title, resizable, closable, false, false);
  216.     }
  217.  
  218.     /** 
  219.      * Creates a non-iconifiable JInternalFrame with the specified title 
  220.      * and with resizability, closability, and maximizability specified.
  221.      *
  222.      * @param title       the String to display in the title bar.
  223.      * @param resizable   if true, the frame can be resized
  224.      * @param closable    if true, the frame can be closed
  225.      * @param maximizable if true, the frame can be maximized
  226.      */
  227.     public JInternalFrame(String title, boolean resizable, boolean closable,
  228.                           boolean maximizable) {
  229.         this(title, resizable, closable, maximizable, false);
  230.     }
  231.  
  232.     /** 
  233.      * Creates a JInternalFrame with the specified title and 
  234.      * with resizability, closability, maximizability, and iconifiability
  235.      * specified.
  236.      *
  237.      * @param title       the String to display in the title bar.
  238.      * @param resizable   if true, the frame can be resized
  239.      * @param closable    if true, the frame can be closed
  240.      * @param maximizable if true, the frame can be maximized
  241.      * @param iconifiable if true, the frame can be iconified
  242.      */
  243.     public JInternalFrame(String title, boolean resizable, boolean closable, 
  244.                                 boolean maximizable, boolean iconifiable) {
  245.         
  246.         setRootPane(createRootPane());
  247.         setLayout(new BorderLayout());
  248.         this.title = title;
  249.         this.resizable = resizable;
  250.         this.closable = closable;
  251.         this.maximizable = maximizable;
  252.         isMaximum = false;
  253.         this.iconable = iconifiable;                         
  254.         isIcon = false;
  255.         setRootPaneCheckingEnabled(true);
  256.         desktopIcon = new JDesktopIcon(this);
  257.     updateUI();
  258.     }
  259.  
  260.     /** 
  261.      * Called by the constructor to set up the JRootPane.
  262.      * @see JRootPane
  263.      */
  264.     protected JRootPane createRootPane() {
  265.         return new JRootPane();
  266.     }
  267.  
  268.     /**
  269.      * Returns the L&F object that renders this component.
  270.      *
  271.      * @return the InternalFrameUI object that renders this component
  272.      */
  273.     public InternalFrameUI getUI() {
  274.         return (InternalFrameUI)ui;
  275.     }
  276.  
  277.     /**
  278.      * Sets the UI delegate for this JInternalFrame.
  279.      * @beaninfo
  280.      *     expert: true
  281.      *     description: The InternalFrameUI implementation that 
  282.      *                  defines the labels look and feel.
  283.      */
  284.     public void setUI(InternalFrameUI ui) {
  285.         boolean checkingEnabled = isRootPaneCheckingEnabled();
  286.         try {
  287.             setRootPaneCheckingEnabled(false);
  288.             super.setUI(ui);
  289.         }
  290.         finally {
  291.             setRootPaneCheckingEnabled(checkingEnabled);
  292.         }
  293.     }
  294.  
  295.     /**
  296.      * Notification from the UIManager that the L&F has changed. 
  297.      * Replaces the current UI object with the latest version from the 
  298.      * UIManager.
  299.      *
  300.      * @see JComponent#updateUI
  301.      */
  302.     public void updateUI() {
  303.         setUI((InternalFrameUI)UIManager.getUI(this));
  304.         invalidate();
  305.         if (desktopIcon != null) {
  306.             desktopIcon.updateUIWhenHidden();
  307.         }
  308.     }
  309.  
  310.     /* This method is called if updateUI was called on the associated
  311.      * JDesktopIcon.  It's necessary to avoid infinite recursion.
  312.      */
  313.     void updateUIWhenHidden() {
  314.         setUI((InternalFrameUI)UIManager.getUI(this));
  315.         invalidate();
  316.         Component[] children = getComponents();
  317.         if (children != null) {
  318.             for(int i = 0; i < children.length; i++) {
  319.                 SwingUtilities.updateComponentTreeUI(children[i]);
  320.             }
  321.         }
  322.     }
  323.  
  324.  
  325.     /**
  326.      * Returns the name of the L&F class that renders this component.
  327.      *
  328.      * @return "InternalFrameUI"
  329.      * @see JComponent#getUIClassID
  330.      * @see UIDefaults#getUI
  331.      * @beaninfo
  332.      *     description: UIClassID
  333.      */
  334.     public String getUIClassID() {
  335.         return uiClassID;
  336.     }
  337.  
  338.     /**
  339.      * Returns whether calls to <code>add</code> and 
  340.      * <code>setLayout</code> cause an exception to be thrown. 
  341.      *
  342.      * @return true if <code>add</code> and <code>setLayout</code> 
  343.      *         are checked
  344.      * @see #addImpl
  345.      * @see #setLayout
  346.      * @see #setRootPaneCheckingEnabled
  347.      */
  348.     protected boolean isRootPaneCheckingEnabled() {
  349.         return rootPaneCheckingEnabled;
  350.     }
  351.  
  352.  
  353.     /**
  354.      * Determines whether calls to <code>add</code> and 
  355.      * <code>setLayout</code> cause an exception to be thrown. 
  356.      * 
  357.      * @param enabled  a boolean value, true if checking is to be
  358.      *        enabled, which cause the exceptions to be thrown
  359.      *
  360.      * @see #addImpl
  361.      * @see #setLayout
  362.      * @see #isRootPaneCheckingEnabled
  363.      */
  364.     protected void setRootPaneCheckingEnabled(boolean enabled) {
  365.         rootPaneCheckingEnabled = enabled;
  366.     }
  367.  
  368.  
  369.     /**
  370.      * Creates a runtime exception with a message like:
  371.      * <pre>
  372.      * "Do not use JFrame.add() use JFrame.getContentPane().add() instead"
  373.      * </pre>
  374.      *
  375.      * @param op  a String indicating the attempted operation. In the
  376.      *            example above, the operation string is "add"
  377.      */
  378.     private Error createRootPaneException(String op) {
  379.         String type = getClass().getName();
  380.         return new Error(
  381.             "Do not use " + type + "." + op + "() use " 
  382.                           + type + ".getContentPane()." + op + "() instead");
  383.     }
  384.  
  385.  
  386.     /**
  387.      * By default, children may not be added directly to a this component,
  388.      * they must be added to its contentPane instead.  For example:
  389.      * <pre>
  390.      * thisComponent.getContentPane().add(child)
  391.      * </pre>
  392.      * An attempt to add to directly to this component will cause an
  393.      * runtime exception to be thrown.  Subclasses can disable this
  394.      * behavior.
  395.      * 
  396.      * @see #setRootPaneCheckingEnabled
  397.      * @exception Error if called with rootPaneChecking true
  398.      */
  399.     protected void addImpl(Component comp, Object constraints, int index) 
  400.     {
  401.         if(isRootPaneCheckingEnabled()) {
  402.             throw createRootPaneException("add");
  403.         }
  404.         else {
  405.             super.addImpl(comp, constraints, index);
  406.         }
  407.     }
  408.  
  409.  
  410.     /**
  411.      * By default the layout of this component may not be set,
  412.      * the layout of its contentPane should be set instead.  
  413.      * For example:
  414.      * <pre>
  415.      * thiComponent.getContentPane().setLayout(new BorderLayout())
  416.      * </pre>
  417.      * An attempt to set the layout of this component will cause an
  418.      * runtime exception to be thrown.  Subclasses can disable this
  419.      * behavior.
  420.      * 
  421.      * @see #setRootPaneCheckingEnabled
  422.      * @exception Error if called with rootPaneChecking true
  423.      */
  424.     public void setLayout(LayoutManager manager) {
  425.         if(isRootPaneCheckingEnabled()) {
  426.             throw createRootPaneException("setLayout");
  427.         }
  428.         else {
  429.             super.setLayout(manager);
  430.         }
  431.     }
  432.  
  433.  
  434. //////////////////////////////////////////////////////////////////////////
  435. /// Property Methods
  436. //////////////////////////////////////////////////////////////////////////
  437.  
  438.     /**
  439.      * Returns the current JMenuBar for this JInternalFrame, or null
  440.      * if no menu bar has been set.
  441.      *
  442.      * @deprecated As of Swing version 1.0.3,
  443.      * replaced by <code>getJMenuBar()</code>.
  444.      */
  445.     public JMenuBar getMenuBar() {
  446.       return getRootPane().getMenuBar();
  447.     }
  448.  
  449.     /**
  450.      * Returns the current JMenuBar for this JInternalFrame, or null
  451.      * if no menu bar has been set.
  452.      *
  453.      * @return  the JMenuBar used by this frame
  454.      * @see #setJMenuBar
  455.      */
  456.     public JMenuBar getJMenuBar() {
  457.     return getRootPane().getJMenuBar();
  458.     }
  459.     
  460.     /**
  461.      * Sets the JMenuBar for this JInternalFrame.
  462.      *
  463.      * @param m  the JMenuBar to use in this frame
  464.      * @see #getJMenuBar
  465.      * @deprecated As of Swing version 1.0.3
  466.      *  replaced by <code>setJMenuBar(JMenuBar m)</code>.
  467.      */
  468.     public void setMenuBar(JMenuBar m) {
  469.         JMenuBar oldValue = getMenuBar();
  470.         getRootPane().setJMenuBar(m);
  471.         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);     
  472.     }
  473.  
  474.     /**
  475.      * Sets the JMenuBar for this JInternalFrame.
  476.      *
  477.      * @param m  the JMenuBar to use in this frame
  478.      * @see #getJMenuBar
  479.      * @beaninfo
  480.      *     preferred: true
  481.      *     description: The menubar for accessing pulldown menus 
  482.      *                  from this frame.
  483.      */
  484.     public void setJMenuBar(JMenuBar m){
  485.         JMenuBar oldValue = getMenuBar();
  486.         getRootPane().setJMenuBar(m);
  487.         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);     
  488.     }
  489.  
  490.     // implements javax.swing.RootPaneContainer
  491.     public Container getContentPane() {
  492.         return getRootPane().getContentPane();
  493.     }
  494.  
  495.  
  496.     /**
  497.      * Sets this JInternalFrame's content pane.
  498.      * 
  499.      * @param contentPane the contentPane object for this frame
  500.      *
  501.      * @exception java.awt.IllegalComponentStateException (a runtime
  502.      *            exception) if the content pane parameter is null
  503.      * @see RootPaneContainer#getContentPane
  504.      * @beaninfo
  505.      *     bound: true
  506.      *     hidden: true
  507.      *     description: The client area of the frame where child 
  508.      *                  components are normally inserted.
  509.      */
  510.     public void setContentPane(Container c) {
  511.         Container oldValue = getContentPane();
  512.         getRootPane().setContentPane(c);
  513.         firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
  514.     }
  515.  
  516.     /**
  517.      * Returns the layeredPane object for this frame.
  518.      *
  519.      * @see RootPaneContainer#setLayeredPane
  520.      * @see RootPaneContainer#getLayeredPane
  521.      */
  522.     public JLayeredPane getLayeredPane() { 
  523.         return getRootPane().getLayeredPane(); 
  524.     }
  525.  
  526.  
  527.     /**
  528.      * Sets this JInternalFrame's layeredPane property.
  529.      * @param layeredPane the layeredPane object for this frame
  530.      *
  531.      * @exception java.awt.IllegalComponentStateException (a runtime
  532.      *            exception) if the layered pane parameter is null
  533.      * @see RootPaneContainer#setLayeredPane
  534.      * @beaninfo
  535.      *     hidden: true
  536.      *     bound: true
  537.      *     description: The pane which holds the various desktop layers.
  538.      */
  539.     public void setLayeredPane(JLayeredPane layered) {
  540.         JLayeredPane oldValue = getLayeredPane();
  541.         getRootPane().setLayeredPane(layered);
  542.         firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);   
  543.     }
  544.  
  545.     /**
  546.      * Returns the glassPane object for this frame.
  547.      *
  548.      * @see RootPaneContainer#setGlassPane
  549.      */
  550.     public Component getGlassPane() { 
  551.         return getRootPane().getGlassPane(); 
  552.     }
  553.  
  554.  
  555.     /**
  556.      * Sets this JInternalFrame's glassPane property.
  557.      * @param glassPane the glassPane object for this frame
  558.      * @see RootPaneContainer#getGlassPane
  559.      * @beaninfo
  560.      *     hidden: true
  561.      *     description: A transparent pane used for menu rendering.
  562.      */
  563.     public void setGlassPane(Component glass) {
  564.         Component oldValue = getGlassPane();
  565.         getRootPane().setGlassPane(glass);
  566.         firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);       
  567.     }
  568.  
  569.     /**
  570.      * Returns the rootPane object for this frame.
  571.      *
  572.      * @see RootPaneContainer#getRootPane
  573.      */
  574.     public JRootPane getRootPane() { 
  575.         return rootPane; 
  576.     }
  577.  
  578.  
  579.     /**
  580.      * Set the rootPane property.  This method is called by the constructor.
  581.      * @beaninfo
  582.      *     hidden: true
  583.      *     beaninfo: The rootPane used by this frame.
  584.      */
  585.     protected void setRootPane(JRootPane root) {
  586.         if(rootPane != null) {
  587.             remove(rootPane);
  588.         }
  589.         JRootPane oldValue = getRootPane();
  590.         rootPane = root;
  591.         if(rootPane != null) {
  592.             boolean checkingEnabled = isRootPaneCheckingEnabled();
  593.             try {
  594.                 setRootPaneCheckingEnabled(false);
  595.                 add(rootPane, BorderLayout.CENTER);
  596.             }
  597.             finally {
  598.                 setRootPaneCheckingEnabled(checkingEnabled);
  599.             }
  600.         }
  601.         firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root); 
  602.     }
  603.  
  604.  
  605.     /**
  606.      * Set the visible state of the object.
  607.      *
  608.      * @param b if true, shows this object; otherwise, hides it 
  609.      */
  610.     public void setVisible(boolean b) {
  611.         super.setVisible(b);
  612.     }
  613.  
  614.     /** 
  615.      * Set that this JInternalFrame can be closed by some user action.
  616.      * @param b a boolean value, where true means the frame can be closed 
  617.      * @beaninfo
  618.      *     preferred: true
  619.      *           bound: true
  620.      *     description: Indicates whether this frame can be closed.
  621.      */
  622.     public void setClosable(boolean b) {
  623.         closable = b;
  624.     }
  625.  
  626.     /** 
  627.      * Returns whether this JInternalFrame be closed by some user action. 
  628.      * @return true if the frame can be closed 
  629.      */
  630.     public boolean isClosable() {
  631.         return closable;
  632.     }
  633.  
  634.     /** 
  635.      * Returns whether this JInternalFrame is currently closed. 
  636.      * @return true if the frame is closed 
  637.      */
  638.     public boolean isClosed() {
  639.         return isClosed;
  640.     }
  641.  
  642.     /** 
  643.      * Calling this method with a value of <code>true</code> to close
  644.      * the frame.
  645.      *
  646.      * @param b a boolean, where true means "close the frame"
  647.      * @exception PropertyVetoException when the attempt to set the 
  648.      *            property is vetoed by the receiver.
  649.      * @beaninfo
  650.      *           bound: true
  651.      *     constrained: true
  652.      *     description: Indicates that the frame has been closed.
  653.      */
  654.     public void setClosed(boolean b) throws PropertyVetoException {
  655.         if (isClosed == b) {
  656.             return;
  657.         }
  658.  
  659.         Boolean oldValue = isClosed ? Boolean.TRUE : Boolean.FALSE; 
  660.         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  661.         fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue);
  662.         isClosed = b;
  663.         if (isClosed) {
  664.             /* Dispatch a closed event to any listeners.  We can't post
  665.              * an event since firing IS_CLOSED_PROPERTY causes this
  666.              * frame to be removed from its parent, which causes any
  667.              * of its events on the EventQueue to get purged.
  668.              */
  669.       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
  670.       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
  671.       opened = false;
  672.         } else if (!opened) {
  673.         fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
  674.             opened = true;
  675.         }
  676.         firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue);
  677.     }
  678.  
  679.     /** 
  680.      * Set that the JInternalFrame can be resized by some user action.
  681.      *
  682.      * @param b  a boolean, where true means the frame can be resized 
  683.      * @beaninfo
  684.      *     preferred: true
  685.      *           bound: true
  686.      *     description: Determines whether the frame can be resized 
  687.      *                  by the user.
  688.      */
  689.     public void setResizable(boolean b) {
  690.         resizable = b;
  691.     }
  692.  
  693.     /** 
  694.      * Returns whether the JInternalFrame can be resized by some user action.
  695.      *
  696.      * @return true if the frame can be resized
  697.      */ 
  698.     public boolean isResizable() {
  699.         // don't allow resizing when maximized.
  700.         return isMaximum ? false : resizable; 
  701.     }
  702.  
  703.     /** 
  704.      * Set that the JInternalFrame can be made an icon by some user action. 
  705.      *
  706.      * @param b  a boolean, where true means the frame can be iconified 
  707.      * @beaninfo:
  708.      *     preferred: true
  709.      *     bound: true
  710.      *     description: Determines whether this frame can be iconified.
  711.      */
  712.     public void setIconifiable(boolean b) {
  713.         iconable = b;
  714.     }
  715.  
  716.     /** 
  717.      * Returns whether the JInternalFrame can be iconified by some user action.
  718.      *
  719.      * @return true if the frame can be iconified
  720.      */ 
  721.     public boolean isIconifiable() {
  722.         return iconable; 
  723.     }
  724.  
  725.     /** 
  726.      * Returns whether the JInternalFrame is currently iconified.
  727.      *
  728.      * @return true if the frame is iconified
  729.      */ 
  730.     public boolean isIcon() {
  731.         return isIcon;
  732.     }
  733.  
  734.     /** 
  735.      * Iconizes and deconizes the frame.
  736.      *
  737.      * @param b a boolean, where true means to iconify the frame and
  738.      *          false means to deiconify it
  739.      * @exception PropertyVetoException when the attempt to set the 
  740.      *            property is vetoed by the receiver.
  741.      * @beaninfo
  742.      *           bound: true
  743.      *     constrained: true
  744.      *     description: The image displayed when this frame is minimized.
  745.      */
  746.     public void setIcon(boolean b) throws PropertyVetoException {
  747.         if (isIcon == b) {
  748.             return;
  749.         }
  750.  
  751.         Boolean oldValue = isIcon ? Boolean.TRUE : Boolean.FALSE; 
  752.         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  753.         fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
  754.         isIcon = b;
  755.         firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
  756.     if (b)
  757.       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
  758.     else
  759.       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
  760.     }
  761.  
  762.     /** 
  763.      * Set that the JInternalFrame can be maximized by some user action.
  764.      *
  765.      * @param b a boolean  where true means the frame can be maximized 
  766.      * @beaninfo
  767.      *         bound: true
  768.      *     preferred: true
  769.      *     description: Determines whether this frame can be maximized.
  770.      */
  771.     public void setMaximizable(boolean b) {
  772.         maximizable = b;
  773.     }
  774.  
  775.     /** 
  776.      * Returns whether the JInternalFrame can be maximized by some user action.
  777.      *
  778.      * @return true if the frame can be maximized 
  779.      */
  780.     public boolean isMaximizable() {
  781.         return maximizable; 
  782.     }
  783.  
  784.     /** 
  785.      * Returns whether the JInternalFrame is currently maximized.
  786.      *
  787.      * @return true if the frame is maximized 
  788.      */
  789.     public boolean isMaximum() {
  790.         return isMaximum;
  791.     }
  792.  
  793.     /**
  794.      * Maximizes and restores the frame.  A maximized frame is resized to
  795.      * fully fit the JDesktopPane area associated with the JInternalFrame.
  796.      * A restored frame's size is set to the JInternalFrame's actual size.
  797.      *
  798.      * @param b  a boolean, where true maximizes the frame and false
  799.      *           restores it
  800.      * @exception PropertyVetoException when the attempt to set the 
  801.      *            property is vetoed by the receiver.
  802.      * @beaninfo
  803.      *     constrained: true
  804.      *     description: Indicates whether the frame is maximized.
  805.      */
  806.     public void setMaximum(boolean b) throws PropertyVetoException {
  807.         if (isMaximum == b) {
  808.             return;
  809.         }
  810.  
  811.         Boolean oldValue = isMaximum ? Boolean.TRUE : Boolean.FALSE;
  812.         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  813.         fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
  814.         isMaximum = b;
  815.         firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
  816.     }
  817.  
  818.     /**
  819.      * Returns the title of the JInternalFrame.
  820.      *
  821.      * @return a String containing the frame's title
  822.      * @see #setTitle
  823.      */
  824.     public String getTitle() {
  825.         return title;
  826.     }
  827.  
  828.     /** 
  829.      * Sets the JInternalFrame title. 
  830.      * @see #getTitle
  831.      *
  832.      * @param title  the String to display in the title bar
  833.      * @beaninfo:
  834.      *     preferred: true
  835.      *     bound: true
  836.      *     description: The text displayed in the title bar.
  837.      */
  838.     public void setTitle(String title) {
  839.         String oldValue = this.title;
  840.         this.title = title;
  841.         firePropertyChange(TITLE_PROPERTY, oldValue, title);
  842.     }
  843.  
  844.     /**
  845.      * Selects and deselects the JInternalFrame.
  846.      * A JInternalFrame normally draws it's title bar differently if it is
  847.      * the selected frame, which indicates to the user that this 
  848.      * internalFrame has the focus.
  849.      *
  850.      * @param selected  a boolean, where true means the frame is selected
  851.      *                  (currently active) and false means it is not
  852.      * @exception PropertyVetoException when the attempt to set the 
  853.      *            property is vetoed by the receiver.
  854.      * @beaninfo
  855.      *     constrained: true
  856.      *           bound: true
  857.      *     description: Indicates whether this frame is currently 
  858.      *                  the active frame.
  859.      */
  860.     public void setSelected(boolean selected) throws PropertyVetoException {
  861.         if (isSelected == selected) {
  862.             return;
  863.         }
  864.  
  865.         Boolean oldValue = isSelected ? Boolean.TRUE : Boolean.FALSE;
  866.         Boolean newValue = selected ? Boolean.TRUE : Boolean.FALSE;
  867.         fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);
  868.         isSelected = selected;
  869.         firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
  870.     if (isSelected)
  871.       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
  872.     else
  873.       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);      
  874.         repaint();
  875.     }
  876.  
  877.     /**
  878.      * Returns whether the JInternalFrame is the currently "selected" or
  879.      * active frame.
  880.      *
  881.      * @return true if the frame is currently selected (active)
  882.      * @see #setSelected
  883.      */
  884.     public boolean isSelected() {
  885.         return isSelected;
  886.     } 
  887.  
  888.     /** 
  889.      * Sets an image to be displayed in the titlebar of the frame (usually
  890.      * in the top-left corner).
  891.      * This image is not the <code>desktopIcon</code> object, which 
  892.      * is the image displayed in the JDesktop when the frame is iconified.
  893.      *
  894.      * Passing null to this function is valid, but the L&F can choose the
  895.      * appropriate behavior for that situation, such as displaying no icon
  896.      * or a default icon for the L&F.
  897.      *
  898.      * @param icon the Icon to display in the title bar
  899.      * @see #getFrameIcon
  900.      * @beaninfo
  901.      *           bound: true
  902.      *     description: The icon shown in the top-left corner of the frame.
  903.      */
  904.   public void setFrameIcon(Icon icon) {
  905.         Icon oldIcon = frameIcon;
  906.         frameIcon = icon;
  907.         firePropertyChange(MENU_BAR_PROPERTY, oldIcon, icon);  
  908.     }
  909.  
  910.     /** 
  911.      * Returns the image displayed in the title bar of the frame (usually
  912.      * in the top-left corner).
  913.      * 
  914.      * @return the Icon displayed in the title bar
  915.      * @see #setFrameIcon
  916.      */
  917.     public Icon getFrameIcon()  {
  918.         return frameIcon;
  919.     }
  920.  
  921.     /**
  922.      * Get the background color of this object.
  923.      *
  924.      * @return the background color, if supported, of the object; 
  925.      * otherwise, null
  926.      */
  927.     public Color getBackground() {
  928.         return getContentPane().getBackground();
  929.     }
  930.  
  931.     /**
  932.      * Set the background color of this object.
  933.      * (For transparency, see <code>isOpaque</code>.)
  934.      *
  935.      * @param c the new Color for the background
  936.      * @see #isOpaque
  937.      */
  938.     public void setBackground(Color c) {
  939.         getContentPane().setBackground(c);
  940.     }
  941.  
  942.     /**
  943.      * Get the foreground color of this object.
  944.      *
  945.      * @return the foreground color, if supported, of the object; 
  946.      * otherwise, null
  947.      */
  948.     public Color getForeground() {
  949.         return getContentPane().getForeground();
  950.     }
  951.  
  952.     /**
  953.      * Set the foreground color of this object.
  954.      *
  955.      * @param c the new Color for the foreground
  956.      */
  957.     public void setForeground(Color c) {
  958.         getContentPane().setForeground(c);
  959.     }
  960.  
  961.     /** Convenience method that moves this component to position 0 if it's 
  962.       * parent is a JLayeredPane.
  963.       */
  964.     public void moveToFront() {
  965.         if(getParent() != null && getParent() instanceof JLayeredPane) {
  966.             JLayeredPane l =  (JLayeredPane)getParent();
  967.             l.moveToFront(this);
  968.         }
  969.     }
  970.  
  971.     /** Convenience method that moves this component to position -1 if it's 
  972.       * parent is a JLayeredPane.
  973.       */
  974.     public void moveToBack() {
  975.         if(getParent() != null && getParent() instanceof JLayeredPane) {
  976.             JLayeredPane l =  (JLayeredPane)getParent();
  977.             l.moveToBack(this);
  978.         }
  979.     }
  980.  
  981.     /** 
  982.      * Convenience method for setting the layer attribute of this component.
  983.      *
  984.      * @param layer  an Integer object specifying this frame's desktop layer
  985.      * @see JLayeredPane
  986.      * @beaninfo
  987.      *     expert: true
  988.      *     description: Specifies what desktop layer is used.
  989.      */
  990.     public void setLayer(Integer layer) {
  991.         if(getParent() != null && getParent() instanceof JLayeredPane) {
  992.             // Normally we want to do this, as it causes the LayeredPane
  993.             // to draw properly.
  994.             JLayeredPane p = (JLayeredPane)getParent();
  995.             p.setLayer(this, layer.intValue(), p.getPosition(this));
  996.         } else {
  997.              // Try to do the right thing
  998.              JLayeredPane.putLayer(this, layer.intValue());
  999.              if(getParent() != null)
  1000.                 getParent().repaint(_bounds.x, _bounds.y, 
  1001.                                     _bounds.width, _bounds.height);
  1002.         }
  1003.     }
  1004.  
  1005.     /** Convenience method for getting the layer attribute of this component.
  1006.      *
  1007.      * @return  an Integer object specifying this frame's desktop layer
  1008.      * @see JLayeredPane
  1009.       */
  1010.     public int getLayer() {
  1011.         return JLayeredPane.getLayer(this);
  1012.     }
  1013.  
  1014.     /** Convenience method that searchs the anscestor heirarchy for a 
  1015.       * JDesktop instance. If JInternalFrame finds none, the desktopIcon
  1016.       * tree is searched.
  1017.       *
  1018.       * @return the JDesktopPane this frame belongs to, or null if none
  1019.       *         is found
  1020.       */
  1021.     public JDesktopPane getDesktopPane() { 
  1022.         Container p;
  1023.  
  1024.         // Search upward for desktop
  1025.         p = getParent();
  1026.         while(p != null && !(p instanceof JDesktopPane))
  1027.             p = p.getParent();
  1028.         
  1029.         if(p == null) {
  1030.            // search it's icon parent for desktop
  1031.            p = getDesktopIcon().getParent();
  1032.            while(p != null && !(p instanceof JDesktopPane))
  1033.                 p = p.getParent();
  1034.         }
  1035.  
  1036.         return (JDesktopPane)p; 
  1037.     }
  1038.  
  1039.     /**
  1040.      * Sets the JDesktopIcon associated with this JInternalFrame.
  1041.      *
  1042.      * @param d the JDesktopIcon to display on the desktop
  1043.      * @see #getDesktopIcon
  1044.      * @beaninfo
  1045.      *           bound: true
  1046.      *     description: The icon shown when this frame is minimized.
  1047.      */
  1048.     public void setDesktopIcon(JDesktopIcon d) { desktopIcon = d; }
  1049.  
  1050.     /** 
  1051.      * Returns the JDesktopIcon used when this JInternalFrame is iconified.
  1052.      *
  1053.      * @return the JDesktopIcon displayed on the desktop
  1054.      * @see #setDesktopIcon
  1055.      */
  1056.     public JDesktopIcon getDesktopIcon() { 
  1057.         return desktopIcon; 
  1058.     }
  1059.  
  1060.  
  1061.     /*
  1062.      * Creates a new EventDispatchThread to dispatch events from. This
  1063.      * method returns when stopModal is invoked.
  1064.      */
  1065.     synchronized void startModal() {
  1066.     /* Since all input will be blocked until this dialog is dismissed,
  1067.      * make sure its parent containers are visible first (this component
  1068.      * is tested below).  This is necessary for JApplets, because
  1069.      * because an applet normally isn't made visible until after its
  1070.      * start() method returns -- if this method is called from start(),
  1071.      * the applet will appear to hang while an invisible modal frame
  1072.      * waits for input.
  1073.      */
  1074.     if (isVisible() && !isShowing()) {
  1075.         Container parent = this.getParent();
  1076.         while (parent != null) {
  1077.         if (parent.isVisible() == false) {
  1078.             parent.setVisible(true);
  1079.         }
  1080.         parent = parent.getParent();
  1081.         }
  1082.     }
  1083.  
  1084.         try {
  1085.             if (SwingUtilities.isEventDispatchThread()) {
  1086.                 EventQueue theQueue = getToolkit().getSystemEventQueue();
  1087.                 while (isVisible()) {
  1088.                     // This is essentially the body of EventDispatchThread
  1089.                     AWTEvent event = theQueue.getNextEvent();
  1090.                     Object src = event.getSource();
  1091.                     // can't call theQueue.dispatchEvent, so I pasted it's body here
  1092.                     /*if (event instanceof ActiveEvent) {
  1093.                       ((ActiveEvent) event).dispatch();
  1094.                       } else */ if (src instanceof Component) {
  1095.                           ((Component) src).dispatchEvent(event);
  1096.                       } else if (src instanceof MenuComponent) {
  1097.                           ((MenuComponent) src).dispatchEvent(event);
  1098.                       } else {
  1099.                           System.err.println("unable to dispatch event: " + event);
  1100.                       }
  1101.                 }
  1102.             } else
  1103.                 while (isVisible())
  1104.                     wait();
  1105.         } catch(InterruptedException e){}
  1106.     }
  1107.   
  1108.     /*
  1109.      * Stops the event dispatching loop created by a previous call to
  1110.      * <code>startModal</code>.
  1111.      */
  1112.     synchronized void stopModal() {
  1113.         notifyAll();
  1114.     }
  1115.   
  1116.     /**
  1117.      * Moves and resizes this component.  Unlike other components,
  1118.      * this implementation also forces re-layout, so that frame
  1119.      * decorations such as the title bar are always redisplayed.
  1120.      *
  1121.      * @param x  an int giving the component's new horizontal position
  1122.      *           measured in pixels from the left of its container
  1123.      * @param y  an int giving the component's new vertical position,
  1124.      *           measured in pixels from the bottom of its container
  1125.      * @param width  an int giving the component's new width in pixels
  1126.      * @param height an int giving the component's new height in pixels
  1127.      */
  1128.     public void reshape(int x, int y, int width, int height) {
  1129.         super.reshape(x, y, width, height);
  1130.         validate();
  1131.         repaint();
  1132.     }
  1133.  
  1134. ///////////////////////////
  1135. // Frame/Window equivalents
  1136. ///////////////////////////
  1137.  
  1138.     /**
  1139.      * Adds the specified internal frame listener to receive internal frame events from
  1140.      * this internal frame.
  1141.      * @param l the internal frame listener
  1142.      */ 
  1143.     public void addInternalFrameListener(InternalFrameListener l) {  // remind: sync ??
  1144.       listenerList.add(InternalFrameListener.class, l);
  1145.       // remind: needed?
  1146.       enableEvents(0);   // turn on the newEventsOnly flag in Component.
  1147.     }
  1148.  
  1149.     /**
  1150.      * Removes the specified internal frame listener so that it no longer
  1151.      * receives internal frame events from this internal frame.
  1152.      * @param l the internal frame listener
  1153.      */ 
  1154.     public void removeInternalFrameListener(InternalFrameListener l) {  // remind: sync??
  1155.       listenerList.remove(InternalFrameListener.class, l);
  1156.     }
  1157.  
  1158.     // remind: name ok? all one method ok? need to be synchronized?
  1159.     protected void fireInternalFrameEvent(int id){  
  1160.       Object[] listeners = listenerList.getListenerList();
  1161.       InternalFrameEvent e = null;
  1162.       for (int i = listeners.length -2; i >=0; i -= 2){
  1163.     if (listeners[i] == InternalFrameListener.class){
  1164.       if (e == null){ 
  1165.         e = new InternalFrameEvent(this, id);
  1166.         //        System.out.println("InternalFrameEvent: " + e.paramString());
  1167.       }
  1168.       switch(e.getID()) {
  1169.       case InternalFrameEvent.INTERNAL_FRAME_OPENED:
  1170.         ((InternalFrameListener)listeners[i+1]).internalFrameOpened(e);
  1171.         break;
  1172.       case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
  1173.         ((InternalFrameListener)listeners[i+1]).internalFrameClosing(e);
  1174.         doDefaultCloseAction();
  1175.         break;
  1176.       case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
  1177.         ((InternalFrameListener)listeners[i+1]).internalFrameClosed(e);
  1178.         break;
  1179.       case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
  1180.         ((InternalFrameListener)listeners[i+1]).internalFrameIconified(e);
  1181.         break;
  1182.       case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
  1183.         ((InternalFrameListener)listeners[i+1]).internalFrameDeiconified(e);
  1184.         break;
  1185.       case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
  1186.         ((InternalFrameListener)listeners[i+1]).internalFrameActivated(e);
  1187.         break;
  1188.       case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
  1189.         ((InternalFrameListener)listeners[i+1]).internalFrameDeactivated(e);
  1190.         break;
  1191.       default:
  1192.         break;
  1193.       }
  1194.     }
  1195.       }
  1196.     }
  1197.  
  1198.     private void doDefaultCloseAction() {
  1199.         switch(defaultCloseOperation) {
  1200.           case HIDE_ON_CLOSE:
  1201.               try {
  1202.                   setClosed(true);
  1203.               } catch (PropertyVetoException pve) {}
  1204.               break;
  1205.           case DISPOSE_ON_CLOSE:
  1206.               try {
  1207.                   setClosed(true);
  1208.                   dispose();  // only executes if close wasn't vetoed.
  1209.               } catch (PropertyVetoException pve) {}
  1210.               break;
  1211.           case DO_NOTHING_ON_CLOSE:
  1212.           default: 
  1213.               break;
  1214.         }
  1215.     }
  1216.  
  1217.     /**
  1218.      * Sets the operation which will happen by default when
  1219.      * the user initiates a "close" on this window.
  1220.      * The possible choices are:
  1221.      * <p>
  1222.      * <ul>
  1223.      * <li>DO_NOTHING_ON_CLOSE - do not do anything - require the
  1224.      * program to handle the operation in the windowClosing
  1225.      * method of a registered InternalFrameListener object.
  1226.      * <li>HIDE_ON_CLOSE - automatically hide the window after
  1227.      * invoking any registered InternalFrameListener objects
  1228.      * <li>DISPOSE_ON_CLOSE - automatically hide and dispose the 
  1229.      * window after invoking any registered InternalFrameListener objects
  1230.      * </ul>
  1231.      * <p>
  1232.      * The value is set to HIDE_ON_CLOSE by default.
  1233.      * @see #addInternalFrameListener
  1234.      * @see #getDefaultCloseOperation
  1235.      */
  1236.     public void setDefaultCloseOperation(int operation) {
  1237.         this.defaultCloseOperation = operation;
  1238.     }
  1239.  
  1240.    /**
  1241.     * Returns the default operation which occurs when the user
  1242.     * initiates a "close" on this window.
  1243.     * @see #setDefaultCloseOperation
  1244.     */
  1245.     public int getDefaultCloseOperation() {
  1246.         return defaultCloseOperation;
  1247.     }
  1248.  
  1249.     /**
  1250.      * Causes subcomponents of this JInternalFrame to be laid out at their
  1251.      * preferred size.
  1252.      * @see       java.awt.Window#pack
  1253.      */
  1254.     public void pack() {
  1255.         Container parent = getParent();
  1256.         if (parent != null && parent.getPeer() == null) {
  1257.             parent.addNotify();
  1258.             addNotify();
  1259.         }
  1260.         setSize(getPreferredSize());
  1261.         validate();
  1262.     }
  1263.  
  1264.     /**
  1265.      * Shows this internal frame, and brings it to the front.
  1266.      * <p>
  1267.      * If this window is not yet visible, <code>show</code> 
  1268.      * makes it visible. If this window is already visible, 
  1269.      * then this method brings it to the front. 
  1270.      * @see       java.awt.Window#show
  1271.      * @see       java.awt.Window#toFront
  1272.      * @see       java.awt.Component#setVisible
  1273.      */
  1274.     public void show() {
  1275.         Container parent = getParent();
  1276.         if (parent != null && parent.getPeer() == null) {
  1277.             parent.addNotify();
  1278.             addNotify();
  1279.         }
  1280.         validate();
  1281.  
  1282.     // bug 4149505
  1283.     if (!opened) {
  1284.       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
  1285.       opened = true;
  1286.     }
  1287.  
  1288.         if (isVisible()) {
  1289.         toFront();
  1290.     } else {
  1291.             super.show();
  1292.         }
  1293.         if (!isSelected()) {
  1294.             try {
  1295.                 setSelected(true);
  1296.             } catch (PropertyVetoException pve) {}
  1297.         }
  1298.     }
  1299.  
  1300.     /**
  1301.      * Disposes of this internal frame. If the frame is not already
  1302.      * closed, a frame-closing event is posted.
  1303.      */
  1304.     public void dispose() {
  1305.         if (isVisible()) {
  1306.             setVisible(false);
  1307.         }
  1308.         if (isSelected()) {
  1309.             try {
  1310.                 setSelected(false);
  1311.             } catch (PropertyVetoException pve) {}
  1312.         }
  1313.         if (!isClosed) {
  1314.       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
  1315.       fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
  1316.         }
  1317.     }
  1318.  
  1319.     /**
  1320.      * Brings this internal frame to the front.
  1321.      * Places this internal frame  at the top of the stacking order
  1322.      * and makes the corresponding adjustment to other visible windows.
  1323.      * @see       java.awt.Window#toFront
  1324.      * @see       #moveToFront
  1325.      */
  1326.     public void toFront() {
  1327.         moveToFront();
  1328.     }
  1329.  
  1330.     /**
  1331.      * Sends this internal frame to the back.
  1332.      * Places this internal frame  at the bottom of the stacking order
  1333.      * and makes the corresponding adjustment to other visible windows.
  1334.      * @see       java.awt.Window#toBack
  1335.      * @see       #moveToBack
  1336.      */
  1337.     public void toBack() {
  1338.         moveToBack();
  1339.     }
  1340.  
  1341.     /**
  1342.      * Gets the warning string that is displayed with this window. 
  1343.      * Since an internal frame is always secure (since it's fully
  1344.      * contained within a window which might need a warning string)
  1345.      * this method always returns null.
  1346.      * @return    null
  1347.      * @see       java.awt.Window#getWarningString
  1348.      */
  1349.     public final String getWarningString() {
  1350.         return null;
  1351.     }
  1352.  
  1353.  
  1354.     /** 
  1355.      * See readObject() and writeObject() in JComponent for more 
  1356.      * information about serialization in Swing.
  1357.      */
  1358.     private void writeObject(ObjectOutputStream s) throws IOException {
  1359.         s.defaultWriteObject();
  1360.     if ((ui != null) && (getUIClassID().equals(uiClassID))) {
  1361.         boolean old = isRootPaneCheckingEnabled();
  1362.         try {
  1363.         setRootPaneCheckingEnabled(false);
  1364.         ui.installUI(this);
  1365.         }
  1366.         finally {
  1367.         setRootPaneCheckingEnabled(old);
  1368.         }
  1369.     }
  1370.     }
  1371.  
  1372.  
  1373.     /**
  1374.      * Returns a string representation of this JInternalFrame. This method 
  1375.      * is intended to be used only for debugging purposes, and the 
  1376.      * content and format of the returned string may vary between      
  1377.      * implementations. The returned string may be empty but may not 
  1378.      * be <code>null</code>.
  1379.      * <P>
  1380.      * Overriding paramString() to provide information about the
  1381.      * specific new aspects of the JFC components.
  1382.      * 
  1383.      * @return  a string representation of this JInternalFrame.
  1384.      */
  1385.     protected String paramString() {
  1386.     String rootPaneString = (rootPane != null ?
  1387.                  rootPane.toString() : "");
  1388.     String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
  1389.                         "true" : "false");
  1390.     String closableString = (closable ? "true" : "false");
  1391.     String isClosedString = (isClosed ? "true" : "false");
  1392.     String maximizableString = (maximizable ? "true" : "false");
  1393.     String isMaximumString = (isMaximum ? "true" : "false");
  1394.     String iconableString = (iconable ? "true" : "false");
  1395.     String isIconString = (isIcon ? "true" : "false");
  1396.     String resizableString = (resizable ? "true" : "false");
  1397.     String isSelectedString = (isSelected ? "true" : "false");
  1398.     String frameIconString = (frameIcon != null ?
  1399.                   frameIcon.toString() : "");
  1400.     String titleString = (title != null ?
  1401.                   title : "");
  1402.     String desktopIconString = (desktopIcon != null ?
  1403.                     desktopIcon.toString() : "");
  1404.     String openedString = (opened ? "true" : "false");
  1405.         String defaultCloseOperationString;
  1406.         if (defaultCloseOperation == HIDE_ON_CLOSE) {
  1407.             defaultCloseOperationString = "HIDE_ON_CLOSE";
  1408.         } else if (defaultCloseOperation == DISPOSE_ON_CLOSE) {
  1409.             defaultCloseOperationString = "DISPOSE_ON_CLOSE";
  1410.         } else if (defaultCloseOperation == DO_NOTHING_ON_CLOSE) {
  1411.             defaultCloseOperationString = "DO_NOTHING_ON_CLOSE";
  1412.         } else defaultCloseOperationString = "";
  1413.  
  1414.     return super.paramString() +
  1415.     ",closable=" + closableString +
  1416.     ",defaultCloseOperation=" + defaultCloseOperationString +
  1417.     ",desktopIcon=" + desktopIconString +
  1418.     ",frameIcon=" + frameIconString +
  1419.     ",iconable=" + iconableString +
  1420.     ",isClosed=" + isClosedString +
  1421.     ",isIcon=" + isIconString +
  1422.     ",isMaximum=" + isMaximumString +
  1423.     ",isSelected=" + isSelectedString +
  1424.     ",maximizable=" + maximizableString +
  1425.     ",opened=" + openedString +
  1426.     ",resizable=" + resizableString +
  1427.     ",rootPane=" + rootPaneString +
  1428.     ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString +
  1429.     ",title=" + titleString;
  1430.     }
  1431.  
  1432. /////////////////
  1433. // Accessibility support
  1434. ////////////////
  1435.  
  1436.     /**
  1437.      * Get the AccessibleContext associated with this JComponent
  1438.      *
  1439.      * @return the AccessibleContext of this JComponent
  1440.      */
  1441.     public AccessibleContext getAccessibleContext() {
  1442.         if (accessibleContext == null) {
  1443.             accessibleContext = new AccessibleJInternalFrame();
  1444.         }
  1445.         return accessibleContext;
  1446.     }
  1447.  
  1448.     /**
  1449.      * The class used to obtain the accessible role for this object.
  1450.      * <p>
  1451.      * <strong>Warning:</strong>
  1452.      * Serialized objects of this class will not be compatible with
  1453.      * future Swing releases.  The current serialization support is appropriate
  1454.      * for short term storage or RMI between applications running the same
  1455.      * version of Swing.  A future release of Swing will provide support for
  1456.      * long term persistence.
  1457.      */
  1458.     protected class AccessibleJInternalFrame extends AccessibleJComponent 
  1459.         implements AccessibleValue {
  1460.  
  1461.         /**
  1462.          * Get the accessible name of this object.  This should almost never
  1463.          * return java.awt.Component.getName(), as that generally isn't
  1464.          * a localized name, and doesn't have meaning for the user.  If the
  1465.          * object is fundamentally a text object (e.g. a menu item), the
  1466.          * accessible name should be the text of the object (e.g. "save").
  1467.          * If the object has a tooltip, the tooltip text may also be an
  1468.          * appropriate String to return.
  1469.          *
  1470.          * @return the localized name of the object -- can be null if this 
  1471.          * object does not have a name
  1472.          * @see #setAccessibleName
  1473.          */
  1474.         public String getAccessibleName() {
  1475.             if (accessibleName != null) {
  1476.                 return accessibleName;
  1477.             } else {
  1478.                 return getTitle();
  1479.             }
  1480.         }
  1481.  
  1482.         /**
  1483.          * Get the role of this object.
  1484.          *
  1485.          * @return an instance of AccessibleRole describing the role of the 
  1486.          * object
  1487.          * @see AccessibleRole
  1488.          */
  1489.         public AccessibleRole getAccessibleRole() {
  1490.             return AccessibleRole.INTERNAL_FRAME;
  1491.         }
  1492.  
  1493.         /**
  1494.          * Get the AccessibleValue associated with this object if one
  1495.          * exists.  Otherwise return null.
  1496.          */
  1497.         public AccessibleValue getAccessibleValue() {
  1498.             return this;
  1499.         }
  1500.  
  1501.  
  1502.         //
  1503.         // AccessibleValue methods
  1504.         //
  1505.  
  1506.         /**
  1507.          * Get the value of this object as a Number.
  1508.          *
  1509.          * @return value of the object -- can be null if this object does not
  1510.          * have a value
  1511.          */
  1512.         public Number getCurrentAccessibleValue() {
  1513.             return new Integer(getLayer());
  1514.         }
  1515.  
  1516.         /**
  1517.          * Set the value of this object as a Number.
  1518.          *
  1519.          * @return True if the value was set.
  1520.          */
  1521.         public boolean setCurrentAccessibleValue(Number n) {
  1522.             if (n instanceof Integer) {
  1523.                 setLayer((Integer) n);
  1524.                 return true;
  1525.             } else {
  1526.                 return false;
  1527.             }
  1528.         }
  1529.  
  1530.         /**
  1531.          * Get the minimum value of this object as a Number.
  1532.          *
  1533.          * @return Minimum value of the object; null if this object does not
  1534.          * have a minimum value
  1535.          */
  1536.         public Number getMinimumAccessibleValue() {
  1537.             return new Integer(Integer.MIN_VALUE);
  1538.         }
  1539.  
  1540.         /**
  1541.          * Get the maximum value of this object as a Number.
  1542.          *
  1543.          * @return Maximum value of the object; null if this object does not
  1544.          * have a maximum value
  1545.          */
  1546.         public Number getMaximumAccessibleValue() {
  1547.             return new Integer(Integer.MAX_VALUE);
  1548.         }
  1549.  
  1550.     } // AccessibleJInternalFrame
  1551.  
  1552.     /**
  1553.      * This component represents an iconified version of a JInternalFrame.
  1554.      * This API should NOT BE USED by Swing applications, as it will go
  1555.      * away in future versions of Swing as its functionality is moved into
  1556.      * JInternalFrame.  This class is public only so that UI objects can
  1557.      * display a desktop icon.  If an application wants to display a
  1558.      * desktop icon, it should create a JInternalFrame instance and
  1559.      * iconify it.
  1560.      * <p>
  1561.      * <strong>Warning:</strong>
  1562.      * Serialized objects of this class will not be compatible with 
  1563.      * future Swing releases.  The current serialization support is appropriate
  1564.      * for short term storage or RMI between applications running the same
  1565.      * version of Swing.  A future release of Swing will provide support for
  1566.      * long term persistence.
  1567.      *
  1568.      * @author David Kloba
  1569.      */
  1570.     static public class JDesktopIcon extends JComponent implements Accessible
  1571.     {
  1572.         JInternalFrame internalFrame;
  1573.  
  1574.         /** Create an icon for an internal frame
  1575.          * @param f  the JInternalFrame for which the icon is created
  1576.          */
  1577.         public JDesktopIcon(JInternalFrame f) {
  1578.             setInternalFrame(f);
  1579.             updateUI();
  1580.         }
  1581.  
  1582.         /**
  1583.          * Returns the L&F object that renders this component.
  1584.          *
  1585.          * @return the DesktopIconUI object that renders this component
  1586.          */
  1587.         public DesktopIconUI getUI() {
  1588.             return (DesktopIconUI)ui;
  1589.         }
  1590.  
  1591.         /**
  1592.          * Sets the L&F object that renders this component.
  1593.          *
  1594.          * @param ui  the DesktopIconUI L&F object
  1595.          * @see UIDefaults#getUI
  1596.          */
  1597.         public void setUI(DesktopIconUI ui) {
  1598.             super.setUI(ui);
  1599.         }
  1600.  
  1601.         /** 
  1602.          * Returns the JInternalFrame that this DesktopIcon is 
  1603.          * associated with. 
  1604.          * @return the JInternalFrame this icon is associated with 
  1605.          */
  1606.         public JInternalFrame getInternalFrame() {
  1607.             return internalFrame;
  1608.         }
  1609.  
  1610.         /** 
  1611.          * Sets the JInternalFrame that this DesktopIcon is 
  1612.          * associated with.
  1613.          * @param f  the JInternalFrame this icon is associated with 
  1614.          */
  1615.         public void setInternalFrame(JInternalFrame f) {
  1616.             internalFrame = f;
  1617.         }
  1618.  
  1619.         /** Convience method to ask the icon for the Desktop object
  1620.          * it belongs to.
  1621.          * @return the JDesktopPane that contains this icon's internal
  1622.          *         frame, or null if none found
  1623.          */
  1624.         public JDesktopPane getDesktopPane() {
  1625.             if(getInternalFrame() != null)
  1626.                 return getInternalFrame().getDesktopPane();
  1627.             return null;
  1628.         }
  1629.  
  1630.         /**
  1631.          * Notification from the UIManager that the L&F has changed. 
  1632.          * Replaces the current UI object with the latest version from the 
  1633.          * UIManager.
  1634.          *
  1635.          * @see JComponent#updateUI
  1636.          */
  1637.         public void updateUI() {
  1638.             boolean hadUI = (ui != null);
  1639.             setUI((DesktopIconUI)UIManager.getUI(this));
  1640.             invalidate();
  1641.  
  1642.             Dimension r = getPreferredSize();
  1643.             setSize(r.width, r.height);
  1644.             
  1645.  
  1646.             if (internalFrame != null && internalFrame.getUI() != null) {  // don't do this if UI not created yet
  1647.                 SwingUtilities.updateComponentTreeUI(internalFrame);
  1648.             }
  1649.         }
  1650.  
  1651.         /* This method is called if updateUI was called on the associated
  1652.          * JInternalFrame.  It's necessary to avoid infinite recursion.
  1653.          */
  1654.         void updateUIWhenHidden() {
  1655.             /* Update this UI and any associated internal frame */
  1656.             setUI((DesktopIconUI)UIManager.getUI(this));
  1657.             invalidate();
  1658.             Component[] children = getComponents();
  1659.             if (children != null) {
  1660.                 for(int i = 0; i < children.length; i++) {
  1661.                     SwingUtilities.updateComponentTreeUI(children[i]);
  1662.                 }
  1663.             }
  1664.         }
  1665.  
  1666.         /**
  1667.          * Returns the name of the L&F class that renders this component.
  1668.          *
  1669.          * @return "DesktopIconUI"
  1670.          * @see JComponent#getUIClassID
  1671.          * @see UIDefaults#getUI
  1672.          */
  1673.         public String getUIClassID() {
  1674.             return "DesktopIconUI";
  1675.         }
  1676.  
  1677.        /////////////////
  1678.        // Accessibility support
  1679.        ////////////////
  1680.  
  1681.         /**
  1682.          * Get the AccessibleContext associated with this JComponent
  1683.          *
  1684.          * @return the AccessibleContext of this JComponent
  1685.          */
  1686.         public AccessibleContext getAccessibleContext() {
  1687.             if (accessibleContext == null) {
  1688.                 accessibleContext = new AccessibleJDesktopIcon();
  1689.             }
  1690.             return accessibleContext;
  1691.         }
  1692.  
  1693.         /**
  1694.          * The class used to obtain the accessible role for this object.
  1695.          * <p>
  1696.          * <strong>Warning:</strong>
  1697.          * Serialized objects of this class will not be compatible with
  1698.          * future Swing releases.  The current serialization support is appropriate
  1699.          * for short term storage or RMI between applications running the same
  1700.          * version of Swing.  A future release of Swing will provide support for
  1701.          * long term persistence.
  1702.          */
  1703.         protected class AccessibleJDesktopIcon extends AccessibleJComponent 
  1704.             implements AccessibleValue {
  1705.  
  1706.             /**
  1707.              * Get the role of this object.
  1708.              *
  1709.              * @return an instance of AccessibleRole describing the role of the 
  1710.              * object
  1711.              * @see AccessibleRole
  1712.              */
  1713.             public AccessibleRole getAccessibleRole() {
  1714.                 return AccessibleRole.DESKTOP_ICON;
  1715.             }
  1716.  
  1717.             /**
  1718.              * Get the AccessibleValue associated with this object if one
  1719.              * exists.  Otherwise return null.
  1720.              */
  1721.             public AccessibleValue getAccessibleValue() {
  1722.                 return this;
  1723.             }
  1724.  
  1725.             //
  1726.             // AccessibleValue methods
  1727.             //
  1728.  
  1729.             /**
  1730.              * Get the value of this object as a Number.
  1731.              *
  1732.              * @return value of the object -- can be null if this object does not
  1733.              * have a value
  1734.              */
  1735.             public Number getCurrentAccessibleValue() {
  1736.                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1737.                 AccessibleValue v = a.getAccessibleValue();
  1738.                 if (v != null) {
  1739.                     return v.getCurrentAccessibleValue();
  1740.                 } else {
  1741.                     return null;
  1742.                 }
  1743.             }
  1744.  
  1745.             /**
  1746.              * Set the value of this object as a Number.
  1747.              *
  1748.              * @return True if the value was set.
  1749.              */
  1750.             public boolean setCurrentAccessibleValue(Number n) {
  1751.                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1752.                 AccessibleValue v = a.getAccessibleValue();
  1753.                 if (v != null) {
  1754.                     return v.setCurrentAccessibleValue(n);
  1755.                 } else {
  1756.                     return false;
  1757.                 }
  1758.             }
  1759.  
  1760.             /**
  1761.              * Get the minimum value of this object as a Number.
  1762.              *
  1763.              * @return Minimum value of the object; null if this object does not
  1764.              * have a minimum value
  1765.              */
  1766.             public Number getMinimumAccessibleValue() {
  1767.                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1768.                 if (a instanceof AccessibleValue) {
  1769.                     return ((AccessibleValue)a).getMinimumAccessibleValue();
  1770.                 } else {
  1771.                     return null;
  1772.                 }
  1773.             }
  1774.  
  1775.             /**
  1776.              * Get the maximum value of this object as a Number.
  1777.              *
  1778.              * @return Maximum value of the object; null if this object does not
  1779.              * have a maximum value
  1780.              */
  1781.             public Number getMaximumAccessibleValue() {
  1782.                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1783.                 if (a instanceof AccessibleValue) {
  1784.                     return ((AccessibleValue)a).getMaximumAccessibleValue();
  1785.                 } else {
  1786.                     return null;
  1787.                 }
  1788.             }
  1789.  
  1790.         } // AccessibleJDesktopIcon
  1791.     }
  1792. }
  1793.